<?php defined('SYSPATH') OR die('No direct script access.');

abstract class Controller_Base extends Kohana_Controller_Template {

	// Disable this controller when Kohana is set to production mode.
	// See http://docs.kohanaphp.com/installation/deployment for more details.
	const ALLOW_PRODUCTION = FALSE;

	// Set the name of the page layout template to use
	public $template = 'smarty3:blank';
	public $template_tips = 'smarty3:tips';

	//Auto rendar
	public $auto_render = true;

	public function before()
	{
		parent::before();

		$this->response->headers('P3P','CP="CAO PSA OUR"');//解决跨域访问别个页面时丢失session的隐私声明
		if (in_array($this->request->method(), array( HTTP_Request::POST, HTTP_Request::PUT, HTTP_Request::DELETE )))
		{
			//header no cache when post
			$this->response->headers(array(
				'Expires' => '0',
				'Cache-Control' => 'no-store,private, post-check=0, pre-check=0, max-age=0',
				'Pragma' => 'no-cache',
			));
		}

		if ($this->request->method() == 'POST' && !$this->check_referrer())
			return $this->error_referrer();

	}

	public function after()
	{
		$this->response->send_headers();
		parent::after();
	}

	protected function checkmethod($method, $uri = '')
	{
		$_method = $this->request->method();
		
		if (strtoupper($method) != $_method) 
		{
			if (!empty($uri))
				$this->redirect($uri);
			return FALSE;
		}
		return TRUE;
	}

	protected function get_validate($keys, $tablename, $prefix = '')
	{
		$validate = Validate::instance()->get_jquery($keys, $tablename, $prefix);
		foreach ($validate['messages'] as $key => $value) {
			$validate['messages'][$key] = __($value['message'],$value['fields']);
		}
		return json_encode($validate);
	}

	protected function _GET($keys)
	{
		$result = array();
		$_keys = _array_selector_subkey($keys);
		foreach ($_keys as $key) {
			$v = $this->request->query($key);
			$result[$key] = isset($v) ? $v : NULL;
		}
		return count($_keys) > 1 ? $result : array_shift($result);
	}

	protected function error($message_name = NULL, $url = FALSE, array $data = array(), $export_data = FALSE)
	{
		//$this->response->status(500);
		$result = $this->_make_output('error',$message_name,$url,$data,$export_data);
		return $result;
	}

	protected function success($message_name = NULL, $url = TRUE, array $data = array(), $export_data = TRUE)
	{
		$result = $this->_make_output('success',$message_name,$url,$data,$export_data);
		return $result;
	}

	protected function failure($message_name = NULL, $url = FALSE, array $data = array(),$export_data = FALSE)
	{
		$result = $this->_make_output('failure',$message_name,$url,$data,$export_data);
		return $result;
	}

	protected function failure_unlogin($url = FALSE)
	{
		$result = $this->failure('default.failure_unlogin',$url);
		return $result;
	}

	protected function failure_auth($url = FALSE)
	{
		$result = $this->failure('default.failure_auth',$url);
		return $result;
	}

	protected function failure_edit_other($url = FALSE)
	{
		$result = $this->failure('default.failure_edit_other',$url);
		return $result;
	}

	protected function failure_view_other($url = FALSE)
	{
		$result = $this->failure('default.failure_view_other',$url);
		return $result;
	}

	protected function failure_noexist($url = FALSE)
	{
		$result = $this->failure('default.failure_noexist',$url);
		return $result;
	}

	protected function failure_noexists($url = FALSE)
	{
		return $this->failure_noexist($url);
	}

	protected function failure_post(array $error_list, $url = FALSE)
	{
		$msg = Kohana::message('common','default.failure_post');
		$content = '';
		foreach ($error_list as $value) {
			$content .= __($msg['list'],array(':line' => __($value['message'],$value['fields'])));
		}
		$msg['content'] = __($msg['content'], array(':list' => $content));
		$msg = array_keyfilter($msg, 'title,content');

		$result = array(
			'result' => 'failure',
			'timeline' => time(),
			'uid' => Auth::instance()->get_user(),
			'message' => $msg,
			'url' => $url,
			'data' => array(),
		);
		$result = $this->output($result);
		return $result;
	}

	protected function failure_attachment($error_no, $url = FALSE)
	{
		$_config = Kohana::$config->load('attachment');
		$msg = Kohana::message('common','attachment.'.$error_no);
		$msg['content'] = __($msg['content'], array(':maxsize' => Text::bytes($_config['maxsize']),':ext' => implode(',', $_config['ext'])));
		$msg = array_keyfilter($msg, 'title,content');
		$result = array(
			'result' => 'failure',
			'timeline' => time(),
			'run-time' => microtime(TRUE) - KOHANA_START_TIME,
			'uid' => Auth::instance()->get_user(),
			'message' => $msg,
			'url' => $url,
			'data' => $export_data ? $data : array(),
		);
		$result = $this->output($result);
		return $result;
	}

	protected function error_referrer($url = FALSE)
	{
		$result = $this->error('default.error_referrer',$url, array('referrer' => $this->request->referrer()));
		return $result;
	}

	protected function error_param($url = FALSE)
	{
		$result = $this->error('default.error_param',$url);
		return $result;
	}

	protected function error_database($url = FALSE)
	{
		$result = $this->error('default.error_database',$url);
		return $result;
	}

	protected function error_server($url = FALSE)
	{
		$result = $this->error('default.error_database',$url);
		return $result;
	}

	protected function check_referrer()
	{
		$referrer = $this->request->referrer();
		$host = $_SERVER['HTTP_HOST'];

		return empty($referrer) || preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $referrer) == preg_replace("/([^\:]+).*/", "\\1", $host);
	}

	protected function _make_output($type, $message_name = NULL, $url = FALSE, array $data = array(), $export_data = FALSE)
	{
		$msg = $message_name;
		if (!is_array($message_name))
		{
			$msg = !empty($message_name) ? Kohana::message('common',$message_name) : array();
			$default = Kohana::message('common','default.'.$type);
			$msg = _extends($msg, $default); //填充

			foreach ($msg as $key => $value) 
				$msg[$key] = empty($data) ?  $value : __($value, array_flatten($data,'/',':')); //转化成有意义的文字
		}
		
		$msg = array_keyfilter($msg, 'title,content');
		$result = array(
			'result' => $type,
			'timeline' => time(),
			'run-time' => microtime(TRUE) - KOHANA_START_TIME,
			'uid' => Auth::instance()->get_user(),
			'message' => $msg,
			'url' => $url,
			'data' => $export_data ? $data : array(),
		);
		return $this->output($result);
	}

	public function output(array $data)
	{
		$of = strtolower($this->request->query('of'));
		$jsonp = $this->request->query('jsonp'); empty($jsonp) && $jsonp = $this->request->query('callback');
		switch ($of) {
			case 'xml':
			case 'yaml':
			case 'json':
			case 'jsonp':
			case 'script':
			case 'csv':
			case 'excel':
			case 'text':
				$of .= ':';
				break;
			case 'html':
				$of = $this->template_tips;
				break;
			default:
				if ($this->request->is_ajax())
					$of = empty($jsonp) ? 'json:' : 'jsonp:';
				else
					$of = $this->template_tips;
				break;
		}
		if (!($this->template instanceof View))
			 $this->template = View::factory($of);

		$this->template->_plain = true;
		$this->template->_data = $data;
		!empty($jsonp) && $this->template->_jsonp = $jsonp;
		$this->template->set_filename($of);

		//设置其他Template变量
		if (method_exists($this, 'set_subtitle'))
			$this->set_subtitle('tips',$data['message']['title']);
		if (!empty($this->user))
			$this->template->_user = array_keyfilter($this->user,'uid,username,realname');
		unset(/*$this->template->_user,*/$this->template->_group,$this->template->_fields);
		
		$result = $this->template->render();
		$this->response->send_headers();
		echo $result;die();
		//throw new Kohana_Exception($result);
		return $result;
	}
	

	/**
	 * 返回页码HTML
	 *
	 * @param integer $count 文章总数量
	 * @param integer $pagesize 每页显示多少条文章
	 * @param integer $curpage 当前页码
	 * @param string $url 页面URL,会被加上参数page=123
	 * @param integer $maxpages 最大显示页码，默认0则表示以实际页码为准
	 * @param integer $page 页面上展示多少个页码
	 * @param boolean $autogoto 根据URL而解析出锚点，以便用户点击之后自动跳转到锚点
	 * @param boolean $simple 如果为TRUE,则只会显示页码，而不会显示一些额外的东西
	 * @return string 根据上述条件返回页码的HTML代码
	 */
	function page_multi($count, $pagesize, $curpage, $url, $maxpages = 0, $page = 10, $autogoto = FALSE, $simple = FALSE) {

		$url_hash = '';
		if(strpos($url, '#') !== FALSE)
		{
			list($url, $url_hash) = explode('#', $url);
			$url_hash = '#'.$url_hash;
		}

		$showkbd = TRUE;$shownum = FALSE;
		$lang = array();
		$lang['prev'] = Kohana::message('common','page.prev');
		$lang['next'] = Kohana::message('common','page.next');
		$lang['total'] = Kohana::message('common','page.total');
		$lang['goto'] = Kohana::message('common','page.goto');
		$lang['page'] = Kohana::message('common','page.page');
		$lang['button'] = Kohana::message('common','page.button');

		$multipage = '';
		$url .= strpos($url, '?') !== FALSE ? '&amp;' : '?';

		$realpages = 1;
		$page_next = 0;
		if($count > $pagesize) {

			$offset = floor($page * 0.5);

			$realpages = @ceil($count / $pagesize);
			$pages = $maxpages && $maxpages < $realpages ? $maxpages : $realpages;

			if($page > $pages) {
				$from = 1;
				$to = $pages;
			} else {
				$from = $curpage - $offset;
				$to = $from + $page - 1;
				if($from < 1) {
					$to = $curpage + 1 - $from;
					$from = 1;
					if($to - $from < $page) {
						$to = $page;
					}
				} elseif($to > $pages) {
					$from = $pages - $page + 1;
					$to = $pages;
				}
			}
			$page_next = $to;

			$multipage = ($curpage > 1 && !$simple ? '<a href="'.$url.'page='.($curpage - 1).$url_hash.'" >'.$lang['prev'].'</a>' : '').($curpage - $offset > 1 && $pages > $page ? '<a href="'.$url.'page=1'.$url_hash.'" class="first">1 ...</a>' : '');
			for($i = $from; $i <= $to; $i++) {
				$multipage .= $i == $curpage ? '<a href="javascript:void(0)" class="hover">'.$i.'</a>' :
				'<a href="'.$url.'page='.$i.$url_hash.'">'.$i.'</a>';
			}

			$multipage .= ($to < $pages ? '<a href="'.$url.'page='.$pages.$url_hash.'" class="last">... '.$realpages.'</a>' : '').
			($curpage < $pages && !$simple ? '<a href="'.$url.'page='.($curpage + 1).$url_hash.'" class="nxt">'.$lang['next'].'</a>' : '').($shownum && !$simple ? __($lang['total'],array(':total'  => $count)) : '');
			$multipage = $multipage ? ($showkbd && !$simple && $pages > $page  ? '
	<div class="next"><div class="pagen">'.$lang['goto'].'<input id="gogo" type="text" onkeydown="if(event.keyCode==13) {window.location=\''.$url.'page=\'+this.value; }" style="width:22px;"/>'.$lang['page'].'</div><div class="go"><a href="javascript:window.location=\''.$url.'page=\' + document.getElementById(\'gogo\').value;">'.$lang['button'].'</a></div></div>': '') . '<div class="pagenum">'.$multipage.'</div>' : '';
		}
		$maxpage = $realpages;
		return $multipage;
	}
	/**
	 * 返回页码的Array
	 *
	 * @param integer $count 文章总数量
	 * @param integer $pagesize 每页显示多少条文章
	 * @param integer $curpage 当前页码
	 * @param string $url 页面URL,会被加上参数page=123
	 * @param integer $maxpages 最大显示页码，默认0则表示以实际页码为准
	 * @param integer $page 页面上展示多少个页码
	 * @return array 根据上述条件返回页码的Array
	 */
	public function page_array($count, $pagesize, $curpage, $url, $maxpages = 0, $page = 10)
	{
		$url_hash = '';
		if(strpos($url, '#') !== FALSE)
		{
			list($url, $url_hash) = explode('#', $url);
			$url_hash = '#'.$url_hash;
		}
		$url .= strpos($url, '?') !== FALSE ? '&amp;' : '?';

		$lang = array(
			'prev' => Kohana::message('common','page.prev'),
			'next' => Kohana::message('common','page.next'),
		);
		$realpages = 1;
		$page_next = 0;
		$multipage = array();
		if($count > $pagesize) {
			$offset = floor($page * 0.5);

			$realpages = @ceil($count / $pagesize);
			$pages = $maxpages && $maxpages < $realpages ? $maxpages : $realpages;

			if($page > $pages) {
				$from = 1;
				$to = $pages;
			} else {
				$from = $curpage - $offset;
				$to = $from + $page - 1;
				if($from < 1) {
					$to = $curpage + 1 - $from;
					$from = 1;
					if($to - $from < $page) {
						$to = $page;
					}
				} elseif($to > $pages) {
					$from = $pages - $page + 1;
					$to = $pages;
				}
			}
			$page_next = $to;
			$curpage > 1 && $multipage['prev'] = array(
				'page' => $curpage - 1,
				'text' => $lang['prev'],
				'url' => $url.'page='.($curpage - 1).$url_hash,
				'enabled' => $curpage > 1,
			);

			$curpage - $offset > 1 && $pages > $page && $multipage['pages'][] = array(
				'page' => 1,
				'text' => '1 ...',
				'url' => $url.'page=1'.$url_hash,
				'enabled' => TRUE,
			);
			for($i = $from; $i <= $to; ++$i)
			{
				$multipage['pages'][] = array(
					'text' => $i,
					'page' => $i,
					'url' => $url.'page='.$i.$url_hash,
					'enabled' => $i != $curpage,
				);
			}
			$to < $pages && $multipage['pages'][] = array(
				'page' => $pages,
				'text' => '... '.$realpages,
				'url' => $url.'page='.$pages.$url_hash,
				'enabled' => $i != $curpage,
			);
			$curpage < $pages && $multipage['next'] = array(
				'page' => $curpage + 1,
				'text' => $lang['next'],
				'url' => $url.'page='.($curpage + 1).$url_hash,
				'enabled' => $curpage < $pages,
			);
		}
		return $multipage;
	}
}
